package com.video.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.video.api.dto.InsertVideoDto;
import com.video.common.utils.UserContext;
import com.video.user.config.MinIOConfigProperties;
import com.video.common.result.PageResult;
import com.video.common.utils.DelFile;
import com.video.user.domain.dto.UpdateVideoCountDto;
import com.video.user.domain.dto.QueryPageDto;
import com.video.user.domain.dto.VideoDto;
import com.video.user.domain.entity.CollectUser;
import com.video.user.domain.entity.LikeUser;
import com.video.user.domain.entity.VideoList;
import com.video.user.mapper.VideoListMapper;
import com.video.user.service.IVideoListService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.minio.MinioClient;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author la
 * @since 2024-11-09
 */
@Service
public class VideoListServiceImpl extends ServiceImpl<VideoListMapper, VideoList> implements IVideoListService {

    @Autowired
    private MinioClient minioClient;
    @Autowired
    private  MinIOConfigProperties minIOConfigProperties;
    @Autowired
    private RestHighLevelClient client;

    /*
     * 新增或编辑视频
     * */
    @Override
    public void InsertList(InsertVideoDto dto) {

        VideoList videoList = BeanUtil.copyProperties(dto, VideoList.class);
        videoList.setType(dto.getType());
        videoList.setUserId(dto.getUserId()!=null?dto.getUserId():UserContext.getUser());
        videoList.setIsTop(dto.getIsTop()!=null?dto.getIsTop():2);
        // 判断是否存在id
        this.saveOrUpdate(videoList);
    }

    /*
     * 分页查询视频列表
     * */
    @Override
    public PageResult queryVideoList(QueryPageDto dto) {
        // 页码参数校验
        dto.validateParams();

        Page<VideoList> page = lambdaQuery()
                .orderByDesc(VideoList::getId)
                .eq(dto.getUserId() != null,VideoList::getUserId, dto.getUserId())
                .page(new Page<>(dto.getPage(), dto.getPageSize()));
        System.out.println("用户id"+dto.getUserId());
        System.out.println("用户视频"+page.getRecords());

        return new PageResult(page.getTotal(), page.getRecords());
    }

    /**
     * 删除视频
     * @param id
     */
    @Override
    public void removeVideoById(Long id) {
        VideoList info = this.lambdaQuery().eq(VideoList::getId, id).one();
        DelFile.deleteFolder(minioClient, minIOConfigProperties.getBucket(), info.getFileRemote());
        this.removeById(id);
    }


    /*
     * 新增数量
     * */
    @Override
    @Transactional
    public void updateVideoCount(UpdateVideoCountDto dto) {
        // 获取执行语句
        String typeStr = dto.createTypeStr();
        // 执行sql
        if (typeStr != null) {
            UpdateWrapper<VideoList> wrapper = new UpdateWrapper<VideoList>().eq("id", dto.getVideoId())
                    .setSql(typeStr);
            this.update(wrapper);

        }

        // 判断类型
        switch (dto.getType()) {
            case 1:
                executeLike(dto.getVideoId(), dto.getIncrease());
                break;
            case 3:
                executeCollect(dto.getVideoId(), dto.getIncrease());
                break;
        }

    }

    /**
     * 使用es查询视频
     * @param keywords
     * @param highLevelClient
     * @return
     */
    @Override
    public PageResult searchList(VideoDto keywords, RestHighLevelClient highLevelClient) throws IOException {
        // 创建搜索请求
        SearchRequest searchRequest = new SearchRequest("videolist");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        // 构建查询条件
        sourceBuilder.query(QueryBuilders.matchQuery("title", keywords.getKeywords()));
        // 执行查询
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 设置搜索源
        searchRequest.source(sourceBuilder);

        // 处理搜索结果
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }

        return null;
    }

    // 执行喜欢表的插入和删除
    private void executeLike(Long videoId, Boolean increase) {
        LikeUser userLike = LikeUser.builder()
                .userId(UserContext.getUser())
                .videoId(videoId)
                .createTime(System.currentTimeMillis())
                .build();
        // 如果为新增
        if (increase) {
            // 加入喜欢表
            Db.save(userLike);
        } else {
            // 查询要删除的数据id
            LikeUser likeUser = Db.lambdaQuery(LikeUser.class)
                    .eq(LikeUser::getVideoId, videoId)
                    .eq(LikeUser::getUserId, UserContext.getUser())
                    .one();
            Db.removeById(likeUser);
        }
    }

    // 执行收藏表的插入和删除
    private void executeCollect(Long videoId, Boolean increase) {
        CollectUser collect = CollectUser.builder()
                .userId(UserContext.getUser())
                .videoId(videoId)
                .createTime(System.currentTimeMillis())
                .build();
        // 如果为新增
        if (increase) {
            // 加入喜欢表
            Db.save(collect);
        } else {
            // 查询要删除的数据id
            CollectUser collectUser = Db.lambdaQuery(CollectUser.class)
                    .eq(CollectUser::getVideoId, videoId)
                    .eq(CollectUser::getUserId, UserContext.getUser())
                    .one();
            Db.removeById(collectUser);
        }
    }
}
